// src/App.tsx
import React, { useState, useEffect, useRef, useCallback } from 'react';
import useMenuContext from '../hooks/useMenuContext';
import useColorPicker from '../hooks/useColorPicker';
import useConnections, { getConnectionPosition, getArrowPoints } from '../hooks/useConnections';
import useResizeCard from '../hooks/useResizeCard';
import type { Card, Tab } from '../types';
import useDragView from '../hooks/useDragView';
import { getAllCards, getAllConnections, createCard, updateCard, deleteCard } from '../api';

import '../App.css';
interface CardsViewsProps {
    tab: Tab;
}

const CardsViews = ({ tab }: CardsViewsProps) => {
    // 状态管理
    const [cards, setCards] = useState<Card[]>([]);
    const [editingCardId, setEditingCardId] = useState<string | null>(null);

    const containerRef = useRef<HTMLDivElement>(null);

    const timerRef = useRef<number>(null);

    // 视图缩放与拖拽 - 使用传入的scale和offset作为初始值
    const { offset, scale, isSpacePressed, isDragging, updateOffset, setOffset, startDragView, endDragView, zoomView } = useDragView(containerRef, tab)

    // 颜色选择器
    const { getColorPicker } = useColorPicker();

    const { resizingCardId, resizeStartPos, resizeStartSize, endResize, getResizeHandler } = useResizeCard();

    const [draggingCardId, setDraggingCardId] = useState<string | null>(null);
    const [dragStartPos, setDragStartPos] = useState({ x: 0, y: 0 });

    // 在App组件中添加状态
    const [hoveredCardId, setHoveredCardId] = useState<string | null>(null);

    const getData = async () => {
        const cardsRes = await getAllCards(tab.id);
        setCards(cardsRes.data || []);
        const connRes = await getAllConnections(tab.id);
        setConnections(connRes.data || []);
    }
    // 连线
    const { connections, setConnections, getConnectionHandlers } = useConnections({ refresh: getData, tabId: tab.id });
    // 初始化示例数据
    useEffect(() => {
        getData()
    }, [tab.id]);

    const resetView = useCallback(() => {
        const x = cards.map(card => card.x)
        const y = cards.map(card => card.y)
        const centerX = window.innerWidth / 2;
        const centerY = window.innerHeight / 2;
        setOffset({
            x: centerX - Math.min(...x) - 400,
            y: centerY - Math.min(...y) - 200,
        })
    }, [cards]);

    // 创建新卡片
    const handleCreateCard = useCallback(
        async (clientX: number, clientY: number) => {
            if (!containerRef.current) return;

            // 获取画布容器的位置信息
            const rect = containerRef.current.getBoundingClientRect();

            // 计算鼠标相对于画布容器的位置
            const containerX = clientX - rect.left;
            const containerY = clientY - rect.top;

            // 考虑视图偏移和缩放，计算实际画布坐标
            const x = (containerX - offset.x) / scale;
            const y = (containerY - offset.y) / scale;

            const newCard: Omit<Card, 'id'> = {
                title: '新卡片',
                content: '在这里输入内容...',
                color: '#ffffff',
                x,
                y,
                width: 200,
                height: 150,
                tabId: tab.id,
            };

            createCard(newCard).then((res) => {
                if (res.data) {
                    setCards([...cards, res.data])
                }
            })
        },
        [cards, offset.x, offset.y, scale]
    );

    const handleUpdateAction = useCallback(
        (id: string, updates: Partial<Card>, immediate?: boolean) => {
            updateCard(id, updates).then((res) => {
                const idx = cards.findIndex((card) => card.id === id)
                if (res.data && immediate) {
                    setCards(pre => {
                        pre[idx] = res.data as Card
                        return [...pre]
                    })
                }
            })
        },
        [cards]
    )

    // 更新卡片
    const handleUpdateWaiting = useCallback(
        (id: string, updates: Partial<Card>) => {
            setCards(cards.map((card) => (card.id === id ? { ...card, ...updates } : card)));

            debounced(() => {
                handleUpdateAction(id, updates, false)
            })
        },
        [cards, handleUpdateAction]
    );

    // 删除卡片
    const handleDeleteCard = useCallback(
        (id: string) => {
            deleteCard(id).then(() => {
                getData()
            })
            if (editingCardId === id) {
                setEditingCardId(null);
            }
        },
        [cards, editingCardId]
    );

    // 右键菜单
    const { Menu, handleCardContextMenu } = useMenuContext({ onDeleteCard: handleDeleteCard });

    const debounced = (callback: () => void) => {
        if (timerRef.current) {
            clearTimeout(timerRef.current)
        }
        timerRef.current = window.setTimeout(() => {
            callback()
        }, 500)
    }

    const handleMove = useCallback(
        (e: React.MouseEvent) => {
            if (draggingCardId) {
                const dx = (e.clientX - dragStartPos.x - offset.x) / scale;
                const dy = (e.clientY - dragStartPos.y - offset.y) / scale;

                handleUpdateWaiting(draggingCardId, { x: dx, y: dy })
            } else if (isDragging && isSpacePressed) {
                updateOffset(e)
            } else if (resizingCardId) {
                const deltaX = (e.clientX - resizeStartPos.x) / scale;
                const deltaY = (e.clientY - resizeStartPos.y) / scale;

                const width = Math.max(160, deltaX + resizeStartSize.width)
                const height = Math.max(48, deltaY + resizeStartSize.height)

                handleUpdateWaiting(resizingCardId, { width, height })
            }
        },
        [draggingCardId, dragStartPos, cards, scale, offset, isDragging, isSpacePressed, resizeStartPos, resizingCardId, resizeStartSize]
    );

    // 结束拖拽视图和卡片
    const endDrag = useCallback(() => {
        endDragView()
        setDraggingCardId(null);
        endResize()
    }, []);

    return (
        <>
            <div className="toolbar">
                <span>缩放: {(scale * 100).toFixed(0)}%</span>
                <button onClick={resetView}>重置视图</button>
            </div>

            {Menu}
            <div
                className={`canvas-container ${isSpacePressed ? 'space-pressed' : ''}`}
                ref={containerRef}
                onMouseDown={startDragView}
                onMouseMove={handleMove}
                onMouseUp={endDrag}
                onMouseLeave={endDrag}
                onWheel={zoomView}
                onDoubleClick={(e) => {
                    e.stopPropagation();
                    if (!editingCardId) {
                        handleCreateCard(e.clientX, e.clientY);
                    }
                }}
            >
                {/* 连接线 */}
                <svg
                    className="connections-layer"
                    style={{
                        transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`,
                        transformOrigin: '0 0',
                        width: '10000px',
                        height: '10000px',
                        overflow: 'visible',
                    }}
                >
                    {connections.map((conn) => {
                        const fromCard = cards.find((c) => c.id === conn.from);
                        const toCard = cards.find((c) => c.id === conn.to);

                        if (!fromCard || !toCard) return null;

                        const { fromX, fromY, toX, toY } = getConnectionPosition(fromCard, toCard, conn.fromSide, conn.toSide);
                        const arrowPoints = getArrowPoints(fromX, fromY, toX, toY);

                        return (
                            <g key={conn.id}>
                                <line x1={fromX} y1={fromY} x2={toX} y2={toY} stroke="#cbddec" strokeWidth="2" />
                                <polygon points={arrowPoints.join(',')} fill="#cbddec" />
                            </g>
                        );
                    })}
                </svg>

                {/* 卡片 */}
                <div
                    className="cards-container"
                    style={{ transform: `translate(${offset.x}px, ${offset.y}px) scale(${scale})`, transformOrigin: '0 0' }}
                >
                    {cards.map((card) => (
                        <div
                            key={card.id}
                            className={`card ${editingCardId === card.id ? 'editing' : ''}`}
                            style={{
                                left: card.x,
                                top: card.y,
                                width: card.width,
                                height: card.height,
                                backgroundColor: card.color,
                            }}
                            onMouseEnter={() => setHoveredCardId(card.id)}
                            onMouseLeave={() => setHoveredCardId(null)}
                            onContextMenu={(e) => handleCardContextMenu(e, card.id)}
                        >
                            {/* 移动触手 */}
                            <div
                                className="move-handle"
                                style={{
                                    position: 'absolute',
                                    top: 0,
                                    right: 0,
                                    width: '100%',
                                    height: 16,
                                    cursor: 'move',
                                    display: hoveredCardId === card.id || draggingCardId === card.id ? 'block' : 'none',
                                    zIndex: 10,
                                }}
                                onMouseDown={(e) => {
                                    e.preventDefault();
                                    e.stopPropagation();
                                    const container = containerRef.current;
                                    if (container) {
                                        const rect = container.getBoundingClientRect();
                                        const containerX = e.clientX - rect.left;
                                        const containerY = e.clientY - rect.top;

                                        setDraggingCardId(card.id);
                                        setDragStartPos({
                                            x: containerX - (card.x * scale + offset.x),
                                            y: containerY - (card.y * scale + offset.y),
                                        });
                                    }
                                }}
                            />

                            {getResizeHandler(card, hoveredCardId)}
                            {getConnectionHandlers(card.id, hoveredCardId)}
                            <div className="card-header">
                                <div
                                    className="editable-title"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        setEditingCardId(`title-${card.id}`);
                                    }}
                                >
                                    <input
                                        type="text"
                                        value={card.title}
                                        onChange={(e) => handleUpdateWaiting(card.id, { title: e.target.value })}
                                        placeholder="标题"
                                        autoFocus
                                        onBlur={() => {
                                            setEditingCardId(null)
                                        }}
                                        style={{ width: '100%' }}
                                        // 添加键盘事件支持回车键确认
                                        onKeyDown={(e) => {
                                            if (e.key === 'Enter') {
                                                setEditingCardId(null);
                                            }
                                        }}
                                    />
                                </div>

                                {getColorPicker(card.id, card.color, handleUpdateAction)}
                            </div>
                            <div
                                className="editable-content"
                                onClick={(e) => {
                                    e.stopPropagation();
                                    setEditingCardId(`content-${card.id}`);
                                }}
                            >
                                <textarea
                                    value={card.content}
                                    onChange={(e) => handleUpdateWaiting(card.id, { content: e.target.value })}
                                    placeholder="内容"
                                    autoFocus
                                    onBlur={() => {
                                        setEditingCardId(null)
                                    }}
                                    style={{
                                        width: '100%',
                                        resize: 'none',
                                    }}
                                />
                            </div>
                        </div>
                    ))}
                </div>
            </div>
        </>
    );
};

export default CardsViews;
